<?php

/**
 * 赛事 api类
 */
class matchModel
{


    public function __construct(& $base)
    {
        $this->base = $base;
        $this->db = & $this->base->db;
        $this->redis = & $this->base->redis;
    }
    
    /*
     * 获取赛事详情
     */
    public function getMatchInfo($match_id){
        if(empty($match_id)){
            return false;
        }
        $redis_key = REDIS_PREFIX.'Match_'.$match_id;
        $matchInfo = $this->redis->hgetall($redis_key);
        if(empty($matchInfo)){
            $matchInfo = $this->db->getRowTable('r_match',[],'match_id='.$match_id);
            $this->redis->hmset($redis_key,$matchInfo);
            $this->redis->expire($redis_key,10*24*3600);
        }
        if(!empty($matchInfo)){
            $matchInfo['menu_items'] = $matchInfo['menu_items'] ? json_decode($matchInfo['menu_items'],true) : [];
            $matchInfo['user_tabs'] = $matchInfo['user_tabs'] ? json_decode($matchInfo['user_tabs'],true) : [];
            $matchInfo['group_tabs'] = $matchInfo['group_tabs'] ? json_decode($matchInfo['group_tabs'],true) : [];
            $matchInfo['rule'] = $matchInfo['rule'] ? json_decode($matchInfo['rule'],true) : ['user_rule'=>[],'group_rule'=>[]];
            $matchInfo['discount'] = $matchInfo['discount'] ? json_decode($matchInfo['discount'],true) : [];
            $now = time();
            if($matchInfo['status']==1 && $matchInfo['stime']<=$now && $now<=$matchInfo['etime']){
                $matchInfo['status'] = 2;
            }elseif($matchInfo['status']==1 && $matchInfo['etime']<$now){
                $matchInfo['status'] = 3;
            }
        }
        return $matchInfo;
    }

    /*
     * 插入数据
     */
    public function insert($matchInfo){
        $info['name'] = $matchInfo['name'];
        $info['match_type'] = $matchInfo['match_type'];
        $info['user_count'] = 0;
        $info['group_count'] = 0;
        isset($matchInfo['goods']) && $info['goods'] = json_encode($matchInfo['goods']);
        $info['template_id'] = $matchInfo['template_id'];
        $info['introduce_type'] = $matchInfo['introduce_type'];
        $info['banner_src'] = $matchInfo['banner_src'];
        $info['logo_src'] = $matchInfo['logo_src'];
        $info['sponsor'] = $matchInfo['sponsor'];
        $info['status'] = $matchInfo['status'];
        $info['introduce_url'] = $matchInfo['introduce_url'];
        $info['introduce'] = str_replace(["\r","\n","\t"],'',$matchInfo['introduce']);
        $info['stime'] = strtotime($matchInfo['stime']);
        $info['etime'] = strtotime($matchInfo['etime']);
        $info['menu_items'] = json_encode($matchInfo['menu_items']);
        $info['user_tabs'] = json_encode($matchInfo['user_tabs']);
        $info['group_tabs'] = json_encode($matchInfo['group_tabs']);
        $info['aim_desc'] = $matchInfo['aim_desc'];
        $info['rule'] = json_encode($matchInfo['rule']);
        $info['addtime'] = time();
        $info['limit_member_max'] = $matchInfo['limit_member_max'];
        $info['fee_goods_id'] = $matchInfo['fee_goods_id'];
        $info['is_free_add'] = $matchInfo['is_free_add'];
        $info['discount'] = json_encode($matchInfo['discount']);
        $info['add_introduce'] = $matchInfo['add_introduce'];
        
        return $this->db->insertRowTable('r_match',$info);
    }
    
    /*
     * 更新数据
     */
    public function update($matchInfo){
        $matchInfo['match_id'];
        if(!$matchInfo['match_id']){
            return false;
        }
        
        $match_id = $info['match_id'] = $matchInfo['match_id'];
        $redis_key = REDIS_PREFIX.'Match_'.$match_id;
        $this->redis->del($redis_key);
        
        $info['name'] = $matchInfo['name'];
        $info['match_type'] = $matchInfo['match_type'];
        $info['user_count'] = $matchInfo['user_count'];
        $info['group_count'] = $matchInfo['group_count'];
        isset($matchInfo['goods']) && $info['goods'] = json_encode($matchInfo['goods']);
        $info['template_id'] = $matchInfo['template_id'];
        $info['introduce_type'] = $matchInfo['introduce_type'];
        $info['banner_src'] = $matchInfo['banner_src'];
        $info['logo_src'] = $matchInfo['logo_src'];
        $info['sponsor'] = $matchInfo['sponsor'];
        $info['status'] = $matchInfo['status'];
        $info['introduce'] = str_replace(["\r","\n","\t"],'',$matchInfo['introduce']);
        $info['introduce_url'] = $matchInfo['introduce_url'];
        $info['introduce_type'] = $matchInfo['introduce_type'];
        $info['stime'] = strtotime($matchInfo['stime']);
        $info['etime'] = strtotime($matchInfo['etime']);
        $info['menu_items'] = json_encode($matchInfo['menu_items']);
        $info['user_tabs'] = json_encode($matchInfo['user_tabs']);
        $info['group_tabs'] = json_encode($matchInfo['group_tabs']);
        $info['aim_desc'] = $matchInfo['aim_desc'];
        $info['rule'] = json_encode($matchInfo['rule']);
        $info['limit_member_max'] = $matchInfo['limit_member_max'];
        $info['fee_goods_id'] = $matchInfo['fee_goods_id'];
        $info['is_free_add'] = $matchInfo['is_free_add'];
        $info['discount'] = json_encode($matchInfo['discount']);
        $info['add_introduce'] = $matchInfo['add_introduce'];
        
        return $this->db->updateRowTable('r_match',$info);
    }
    
    /*
     * 获得参赛信息列表
     */
    public function getMatchAddList($match_id,$type,$start=0,$listNum=999,$status=1){
        $sql = "SELECT * FROM r_match_add WHERE `type`='$type' AND match_id='$match_id' AND status='$status' LIMIT $start,$listNum";
        return $this->db->getAll($sql);
    }
    
    /*
     * 获得参赛信息
     */
    public function getMatchAdd($match_id,$uid,$type='all'){
        if($type=='user'){
            $sql = "SELECT id,`type`,uid,gid,name,phone,gender,status FROM r_match_add WHERE uid=$uid AND match_id=$match_id AND `type`='user'";
        }else{
            $groupList = $this->base->load('group')->myGroupList($uid,true);
            $gids = [];
            $group_map = [];
            foreach($groupList as $v){
                $gids[] = $v['gid'];
                $group_map[$v['gid']] = $v['name'];
            }
            if($gids){
                $gids = implode("','",$gids);
                $sql = "SELECT id,`type`,uid,gid,name,phone,gender,status FROM r_match_add WHERE (uid=$uid or gid IN('$gids')) AND match_id=$match_id";
            }else{
                $sql = "SELECT id,`type`,uid,gid,name,phone,gender,status FROM r_match_add WHERE uid=$uid AND match_id=$match_id";
            }
            
            if($type=='group'){
                $sql .= " AND `type`='group'";
            }
        }
        $res = $this->db->getAll($sql);
        
        $user_add_id = null;
        $name = null;
        $phone = null;
        $gender = null;
        $status = null;
        $group_add_info = [];
        foreach($res as $row){
            if($row['type']=='user'){
                $user_add_id = $row['id'];
                $uid = $row['uid'];
                $name = $row['name'];
                $phone = $row['phone'];
                $gender = $row['gender'];
                $status = $row['status'];
            }elseif($row['type']=='group'){
                $group_add_info[] = [
                    'group_add_id' => $row['id'],
                    'gid' => $row['gid'],
                    'status' => $row['status'],
                    'group_name' => $group_map[$row['gid']]
                ];
            }
        }
        return compact('user_add_id','uid','name','phone','gender','status','group_add_info');
        
    }
    
    /*
     * 获得用户个人上次参加信息
     */
    public function getUserLastInfo($uid){
        $res = $this->db->getRowTable('r_match_add',['name','phone','gender'],'uid='.$uid,'id DESC');
        return $res;
    }
    
    /*
     * 获得单个统计结果
     */
    public function getStatistics($matchInfo,$matchAdd){
        $startTime = $matchInfo['stime'];
        $endTime = $matchInfo['etime'];
        $rule = $matchInfo['rule'];
        if(empty($rule)){
            return false;
        }
        //$rule = json_decode($rule);
        
        if($matchAdd['type']=='user'){
            $uid = $matchAdd['uid'];
            $sql = "SELECT * FROM r_data WHERE updatetime BETWEEN $startTime AND $endTime AND uid=$uid AND overSpeed=0";
            $data = $this->db->getAll($sql);
            $rule = $rule['user_rule'];
        }elseif($matchAdd['type']=='group'){
            $gid = $matchAdd['gid'];
            $sql = "SELECT * FROM r_group_run WHERE gid=$gid AND is_delete=0 AND updatetime BETWEEN $startTime AND $endTime";
            $data = $this->db->getAll($sql);
            $rule = $rule['group_rule'];
        }
        
        extract($this->_getDataDay($data));//$data_day,$total_mileage,$total_times,$total_elapsedtime,$best_mileage,$best_elapsedtime
        $dabiao_days = count($data_day);
        
        //是否达标
        $or_result = false;
        foreach($rule as $or_group){
            $and_result = true;
            foreach($or_group as $and_group){
                $res = $this->_getRuleResult($and_group,$data_day,$data);
                if(!$res['dabiao']){
                    $and_result = false;
                    break;
                }
            }
            $or_result = $or_result || $and_result;
        }
        
        $dabiao = $or_result ? 1 : 0;
        
        //最近两次成绩
        $data_last = end($data_day);
        $data_last_but_one = prev($data_day);
        $recent_data = $data_last['date'].$data_last['mileage'].'km/'.$data_last['total_rate'].'次'.' '.$data_last_but_one['date'].$data_last_but_one['mileage'].'km/'.$data_last_but_one['total_rate'].'次';
        
        return compact('total_mileage','total_elapsedtime','total_times','recent_data','dabiao','best_elapsedtime','best_mileage','dabiao_days');
    }
    
    /*
     * 获得每条赛事规则的判定结果
     */
    public function _getRuleResult($rule,&$data_day,&$data){
        extract($rule);//rate,value,unit
        $mileage = 0;
        $elapsedtime = 0;
        $times = 0;
        $days = 0;
        switch($rate){
            case '总计':
                foreach($data_day as $row){
                    $mileage += $row['mileage'];
                    $elapsedtime += $row['elapsedtime'];
                    $times += $row['total_rate'];
                    $days += 1;
                }
                
                break;
            case '每天':
                foreach($data_day as $row){
                    if($mileage == 0){
                        $mileage = $row['mileage'];
                    }elseif($mileage < $row['mileage']){
                        $mileage = $row['mileage'];
                    }
                    if($elapsedtime == 0){
                        $elapsedtime = $row['elapsedtime'];
                    }elseif($elapsedtime < $row['elapsedtime']){
                        $elapsedtime = $row['elapsedtime'];
                    }
                    if($times == 0){
                        $times = $row['total_rate'];
                    }elseif($times < $row['total_rate']){
                        $times = $row['total_rate'];
                    }
                }
                break;
            case '任意天':
                foreach($data_day as $row){
                    if($mileage == 0){
                        $mileage = $row['mileage'];
                    }elseif($mileage > $row['mileage']){
                        $mileage = $row['mileage'];
                    }
                    if($elapsedtime == 0){
                        $elapsedtime = $row['elapsedtime'];
                    }elseif($elapsedtime > $row['elapsedtime']){
                        $elapsedtime = $row['elapsedtime'];
                    }
                    if($times == 0){
                        $times = $row['total_rate'];
                    }elseif($times > $row['total_rate']){
                        $times = $row['total_rate'];
                    }
                }
                break;
            case '每次':
                foreach($data as $row){
                    if($mileage == 0){
                        $mileage = $row['mileage'];
                    }elseif($mileage < $row['mileage']){
                        $mileage = $row['mileage'];
                    }
                    if($elapsedtime == 0){
                        $elapsedtime = $row['elapsedtime'];
                    }elseif($elapsedtime < $row['elapsedtime']){
                        $elapsedtime = $row['elapsedtime'];
                    }
                    $times++;
                }
                break;
        }
        switch($unit){
            case '公里':
                return ['mileage'=>$mileage,'dabiao'=>($mileage >= $value)];
            case '次':
                return ['times'=>$times,'dabiao'=>($times >= $value)];
            case '分钟':
                return ['elapsedtime'=>$elapsedtime,'dabiao'=>($elapsedtime >= $value*60)];
            case '天':
                return ['days'=>$days, 'dabiao'=>($days >= $value)];
        }
    }
    
    /*
     * 参加赛事
     */
    public function joinMatch($match_id,$type,$uid,$name='',$phone='',$gender='',$gid=null,$status=1){
        $matchInfo = $this->getMatchInfo($match_id);
        if($matchInfo['status'] != 1){
            return false;
        }
        if($matchInfo['match_type'] == 0 && $type=='group'){
            return false;
        }
        if($matchInfo['match_type'] == 1 && $type=='user'){
            return false;
        }
        $match_add_id = null;
        if($type=='user'){
            $match_add_id = $this->db->getOne("SELECT id FROM r_match_add WHERE match_id=$match_id AND uid=$uid AND `type`='user' LIMIT 1");
        }else{
            $match_add_id = $this->db->getOne("SELECT id FROM r_match_add WHERE match_id=$match_id AND gid=$gid AND `type`='group' LIMIT 1");
            if($match_add_id){
                return $match_add_id;
            }
        }
        
        $addtime = time();
        $this->db->query('begin');
        $row = compact('match_id','type','uid','gid','name','phone','gender','addtime','status');
        $match_add_id && $row['id'] = $match_add_id;
        $match_add_id = $this->db->insertRowTable('r_match_add',$row);
        
        if($type=='user'){
            $sql = "UPDATE r_match SET user_count=user_count+1 WHERE match_id=$match_id";
        }else{
            $sql = "UPDATE r_match SET group_count=group_count+1 WHERE match_id=$match_id";
        }
        $this->db->update($sql);
        $this->db->query('commit');
        
        $redis_key = REDIS_PREFIX.'Match_'.$match_id;
        $this->redis->del($redis_key);
        
        return $match_add_id;
    }
    
    /*
     * 每晚统计
     */
    public function saveStatistics(){
        $now = time();
        $etime = $now - 3600;
        $sql = "SELECT * FROM r_match WHERE status=1 AND stime<$now AND etime>$etime";
        $matches = $this->db->getAll($sql);
        
        foreach($matches as $match){
            $match_id = $match['match_id'];
            $sql = "SELECT * FROM r_match_add WHERE match_id=$match_id and `status`=1";
            $match_adds = $this->db->getAll($sql);
            $match['rule'] = json_decode($match['rule'],true);
            foreach($match_adds as $match_add){
                $res = $this->getStatistics($match,$match_add);
                $res['id'] = $match_add['id'];
                $this->db->updateRowTable('r_match_add',$res);
            }
        }
    }
    
    /*
     * 获得排名
     */
    public function getRank($match_id,$match_type,$from='dabiao'){
        $field_arr = [
            'total_mileage',
            'total_elapsedtime',
            'best_mileage',
            'best_elapsedtime'
        ];
        
        if($match_type != 1){
            $user_mod = $this->base->load('user');
            $field_arr[] = 'dabiao_days';
            foreach($field_arr as $field){
                $sql = "SELECT uid,$field FROM r_match_add WHERE match_id=$match_id AND type='user' and `status`=1";
                if($from=='dabiao'){
                    $sql .= " AND dabiao=1";
                }
                $sql .= " ORDER BY $field DESC,total_mileage DESC LIMIT 50";
                
                $user_rank[$field] = $this->db->getAll($sql);
                foreach($user_rank[$field] as &$rank){
                    $user = $user_mod->getUserInfo($rank['uid']);
                    $rank['nickname'] = $user['nickname'];
                    $rank['header'] = $user['header'];
                }
            }
        }
        
        if($match_type != 0){
            $group_mod = $this->base->load('group');
            foreach($field_arr as $field){
                $sql = "SELECT gid,$field FROM r_match_add WHERE match_id=$match_id AND type='group' and `status`=1";
                if($from=='dabiao'){
                    $sql .= " AND dabiao=1";
                }
                $sql .= " ORDER BY $field DESC,total_mileage DESC LIMIT 50";
                
                $group_rank[$field] = $this->db->getAll($sql);
                foreach($group_rank[$field] as &$rank){
                    $group =  $group_mod->getGroupInfo($rank['gid']);
                    $rank['name'] = $group['name'];
                    $rank['header'] = $group['header'];
                }
            }
        }
        
        return compact('user_rank','group_rank');
    }
    
    /*
     * 获得每日跑步信息
     */
    public function _getDataDay(&$data){
        $data_day = []; //每日数据
        $total_mileage = 0; //总里程
        $total_elapsedtime = 0; //总时长
        $total_times = 0; //总次数
        $best_mileage = 0; //最佳单次里程
        $best_elapsedtime = 0; //最佳单次时长
        foreach($data as $row){
            $date = date('Y-m-d',$row['updatetime']);
            if(isset($data_day[$date])){
                $data_day[$date]['mileage'] += $row['mileage'];
                $data_day[$date]['elapsedtime'] += $row['elapsedtime'];
                $data_day[$date]['total_rate'] ++;
            }else{
                $data_day[$date]['mileage'] = $row['mileage'];
                $data_day[$date]['elapsedtime'] = $row['elapsedtime'];
                $data_day[$date]['total_rate'] = 1;
                $data_day[$date]['date'] = $date;
            }
            $total_mileage += $row['mileage'];
            $total_elapsedtime += $row['elapsedtime'];
            $total_times += 1;
            if($row['mileage'] > $best_mileage){
                $best_mileage = $row['mileage'];
            }
            if($row['elapsedtime'] > $best_elapsedtime){
                $best_elapsedtime = $row['elapsedtime'];
            }
        }
        
        return compact('data_day','total_mileage','total_times','total_elapsedtime','best_elapsedtime','best_mileage');
    }
    
    /*
     * 获得证书
     */
    public function getCertificate($matchInfo,$uid){
        $startTime = $matchInfo['stime'];
        $endTime = $matchInfo['etime'];
        $match_id = $matchInfo['match_id'];
        $addInfo = $this->getMatchAdd($match_id,$uid);
        extract($addInfo);//$user_add_id,$group_add_id,uid,gid
        
        //个人
        $user_data = null;
        $user_rank = null;
        if($user_add_id){
            $sql = "SELECT mileage,elapsedtime,updatetime FROM r_data WHERE uid=$uid AND updatetime BETWEEN $startTime AND $endTime";
            $data = $this->db->getAll($sql);
            $res = $this->_getDataDay($data);
            $user_data = array_values($res['data_day']);
            $total_mileage = $res['total_mileage'];
            $sql = "SELECT id FROM r_match_add WHERE match_id=$match_id AND `type`='user' AND dabiao=1 AND `status`=1 AND uid=$uid";
            if(!$this->db->getOne($sql)){
                $user_rank = '未达标';
            }else{
                $sql = "SELECT count(*) FROM r_match_add WHERE match_id=$match_id AND `type`='user' AND dabiao=1 AND `status`=1 AND total_mileage > $total_mileage";
                $user_rank = $this->db->getOne($sql)+1;
            }
        }
        //群组
        $group_data_info = [];
        if($group_add_info){
            foreach($group_add_info as &$row){
                $group_data = null;
                $group_rank = null;
                $group_add_id = $row['group_add_id'];
                
                $sql = "SELECT gid FROM r_match_add WHERE id=$group_add_id";
                $gid = $this->db->getOne($sql);
                $sql = "SELECT mileage,elapsedtime,updatetime FROM r_group_run WHERE gid=$gid AND updatetime BETWEEN $startTime AND $endTime";
                $data = $this->db->getAll($sql);
                $res = $this->_getDataDay($data);
                $group_data = array_values($res['data_day']);
                $total_mileage = $res['total_mileage'];
                $sql = "SELECT id FROM r_match_add WHERE match_id=$match_id AND `type`='group' AND dabiao=1 AND `status`=1 AND uid=$uid";
                if(!$this->db->getOne($sql)){
                    $group_rank = '未达标';
                }else{
                    $sql = "SELECT count(*) FROM r_match_add WHERE match_id=$match_id AND `type`='group' AND dabiao=1 AND `status`=1 AND total_mileage > $total_mileage";
                    $group_rank = $this->db->getOne($sql)+1;
                }
                $row['group_data'] = $group_data;
                $row['group_rank'] = $group_rank;
            }
            $group_data_info = $group_add_info;
        }
        return compact('uid','user_data','user_rank','group_data_info');
    }
    
    /*
     * 更新参赛状态
     */
    public function updateAdd($data){
        if(empty($data['id'])){
            return false;
        }
        $info['id'] = $data['id'];
        isset($data['status']) && $info['status'] = $data['status'];
        isset($data['name']) && $info['name'] = $data['name'];
        isset($data['phone']) && $info['phone'] = $data['phone'];
        isset($data['gender']) && $info['gender'] = $data['gender'];
        
        $this->db->updateRowTable('r_match_add',$info);
    }
    
    /*
     * 获得用户成绩
     */
    public function getUserScore($match_id,$user_id){
        return $this->db->getRowTable('r_match_add',['total_mileage','total_elapsedtime','total_times','best_mileage','best_elapsedtime','dabiao_days'],"match_id=$match_id and uid=$user_id and `type`='user' and status=1");
    }
}

?>